package com.wuge.gulimall.member.service.impl;

import com.wuge.common.utils.R;
import com.wuge.gulimall.member.entity.MemberLevelEntity;
import com.wuge.gulimall.member.exception.RepeatPhoneException;
import com.wuge.gulimall.member.exception.RepeatUsernameException;
import com.wuge.gulimall.member.service.MemberLevelService;
import com.wuge.gulimall.member.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuge.common.utils.PageUtils;
import com.wuge.common.utils.Query;

import com.wuge.gulimall.member.dao.MemberDao;
import com.wuge.gulimall.member.entity.MemberEntity;
import com.wuge.gulimall.member.service.MemberService;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Autowired
    MemberLevelService memberLevelService;
    @Autowired
    RestTemplate restTemplate;
    @Override
    public MemberEntity Authlogin(String code) {
//        获取令牌
        RestToken restToken=new RestToken();
        restToken.setCode(code);
     String uri="https://gitee.com/oauth/token?grant_type=authorization_code&code=" + code + "&client_id=" +restToken.getClient_id() + "&redirect_uri=" + restToken.getRedirect_uri() + "&client_secret=" + restToken.getClient_secret();
//        HttpHeaders headers = new HttpHeaders();
//        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
//        ResponseEntity<TokenModel> entity = restTemplate.postForEntity(uri, headers, TokenModel.class);
        MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
//  也支持中文
        params.add("client_id",restToken.getClient_id());
        params.add("grant_type",restToken.getGrant_type());
        params.add("code",restToken.getCode());
        params.add("redirect_uri",restToken.getRedirect_uri());
        params.add("client_secret",restToken.getClient_secret());
        TokenModel tokenModel = restTemplate.postForObject("https://gitee.com/oauth/token", params, TokenModel.class);
        /*根据令牌获取用户信息*/
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("param1",tokenModel.getAccess_token());
        GiteeVo forObject = restTemplate.getForObject("https://gitee.com/api/v5/user?access_token={param1}", GiteeVo.class, map);
        return socialLogin(forObject);
    }
    public MemberEntity socialLogin(GiteeVo giteeVo){
        MemberEntity memberEntity = this.getBaseMapper().selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", giteeVo.getId()));
//        用户首次登录将账号信息存入数据库
        if (memberEntity==null){

            memberEntity=new MemberEntity();
            memberEntity.setNickname(giteeVo.getName());
            memberEntity.setUsername(giteeVo.getLogin());
            memberEntity.setEmail(giteeVo.getEmail());
            memberEntity.setCreateTime(new Date());
            MemberLevelEntity default_status = memberLevelService.list(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1)).get(0);
            memberEntity.setLevelId(default_status.getId());
            memberEntity.setSocialUid(String.valueOf(giteeVo.getId()));
            this.save(memberEntity);
        }
        return memberEntity;



    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(UserRegisterVo member) {
        validatePhone(member.getPhone());
        validateUsername(member.getUserName());
        MemberLevelEntity default_status = memberLevelService.list(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1)).get(0);
        Long level_id=default_status.getId();
        MemberEntity memberEntity=new MemberEntity();
        memberEntity.setLevelId(level_id);
        memberEntity.setCreateTime(new Date());
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        memberEntity.setPassword(bCryptPasswordEncoder.encode(member.getPassword()));
        memberEntity.setMobile(member.getPhone());
        memberEntity.setUsername(member.getUserName());
        memberEntity.setNickname(member.getUserName());
        memberEntity.setGender(0);
        save(memberEntity);
    }
    public void validateUsername(String username) throws RepeatUsernameException {
        Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username));
        if (count>0){
            throw new RepeatUsernameException();
        }
    }
    public void validatePhone(String phone) throws RepeatPhoneException {
        Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count>0){
            throw new RepeatPhoneException();
        }
    }

    @Override
    public boolean login(UserLoginVo userLoginVo, R ok) {
        MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", userLoginVo.getLoginacct()).or().eq("mobile", userLoginVo.getLoginacct()));
        if (memberEntity==null){
            return false;
        }
        String password = memberEntity.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
        boolean b = bCryptPasswordEncoder.matches(userLoginVo.getPassword(), password);
          if (b){
              ok.put("data",memberEntity);
              return true;
          }
        return false;
    }
}